package com.zunipe.until;

import com.zunipe.ZunipeTools;
import com.zunipe.minix.MinecraftClientMixin;
import com.zunipe.screen.AutoAttackOptionScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.util.math.Vec3d;

public class AutoAttackFunction
{
    public static void AutoAttack(MinecraftClient client)
    {
        if (client.player == null)
            return;
        if (Util.autoAttack)
        {
            client.player.sendMessage(new LiteralText("§l自动攻击 §4§l关闭"), true);
            Util.autoAttack = false;
        }
        else
        {
            client.player.sendMessage(new LiteralText("§l自动攻击 §2§l开启"), true);
            Util.autoAttack = true;
            new Thread(() ->
            {
                while (Util.autoAttack)
                {
                    if (client.cameraEntity != null && client.player != null && client.world != null)
                    {
                        Vec3d cameraPos = client.player.getEyePos();
                        Iterable<Entity> it = client.world.getEntities();
                        Entity temp = null;
                        double tempDis = 10000;
                        try
                        {
                            for (Entity entity : it)
                            {
                                if (entity instanceof LivingEntity && !(entity instanceof ArmorStandEntity) && !(entity.equals(client.player)))
                                {
                                    if (((LivingEntity) entity).getHealth() > 0)
                                    {
                                        if (Util.attackTarget == AutoAttackOptionScreen.AttackTarget.MONSTER && !entity.getType().getSpawnGroup().equals(SpawnGroup.MONSTER))
                                            continue;
                                        if (Util.attackTarget == AutoAttackOptionScreen.AttackTarget.PLAYER && !(entity instanceof PlayerEntity))
                                            continue;
                                        double distance = entity.distanceTo(client.player);
                                        if (distance < tempDis && distance <= Util.detectDistance)
                                        {
                                            Vec3d blockPos = entity.getPos();
                                            double x = blockPos.getX() - cameraPos.getX(), y = blockPos.getY() + entity.getEyeHeight(EntityPose.STANDING) - cameraPos.getY(), z = blockPos.getZ() - cameraPos.getZ();
                                            double r = Math.sqrt(x * x + z * z);
                                            double p = -Math.atan2(y, r) / Math.PI * 180.0 + 90;
                                            double f = -Math.atan2(x, z) / Math.PI * 180.0 + 180;
                                            double yaw = client.player.getYaw() % 360 + 180, pitch = client.player.getPitch() + 90;
                                            double minYaw = Math.min(Math.abs(yaw - f), Math.abs(360 - f + yaw));
                                            if (minYaw <= Util.yawScope && Math.abs(p - pitch) <= Util.pitchScope)
                                            {
                                                temp = entity;
                                                tempDis = distance;
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (ArrayIndexOutOfBoundsException exception)
                        {
                            ZunipeTools.LOGGER.error(exception.getMessage());
                        }

                        if (temp == null)
                            continue;

                        Vec3d blockPos = temp.getPos();

                        double x = blockPos.getX() - cameraPos.getX(), y = blockPos.getY() + temp.getEyeHeight(EntityPose.STANDING) - cameraPos.getY(), z = blockPos.getZ() - cameraPos.getZ();
                        double r = Math.sqrt(x * x + z * z);
                        double f = -Math.atan2(x, z);
                        double p = -Math.atan2(y, r);
                        client.cameraEntity.setYaw((float) (f / Math.PI * 180.0));
                        client.cameraEntity.setPitch((float) (p / Math.PI * 180.0));
                        try
                        {
                            Thread.sleep(10);
                        } catch (InterruptedException exception)
                        {
                            ZunipeTools.LOGGER.error(exception.getMessage());
                        }
                        try
                        {
                            if (Util.attackMode.equals(AutoAttackOptionScreen.AttackMode.LEFT) || Util.attackMode.equals(AutoAttackOptionScreen.AttackMode.ALL))
                                ((MinecraftClientMixin) client).doAttackInvoker();
                            if (Util.attackMode.equals(AutoAttackOptionScreen.AttackMode.RIGHT) || Util.attackMode.equals(AutoAttackOptionScreen.AttackMode.ALL))
                                ((MinecraftClientMixin) client).doItemUseInvoker();
                        } catch (ClassCastException e)
                        {
                            ZunipeTools.LOGGER.error(e.getMessage());
                        }
                        try
                        {
                            Thread.sleep(Util.tick);
                        } catch (InterruptedException exception)
                        {
                            ZunipeTools.LOGGER.error(exception.getMessage());
                        }
                    }
                }
            }).start();
        }
    }
}
